package com.ifp.opengate.boot.decode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ifp.core.util.StringUtil;
import com.ifp.opengate.boot.bean.ValidatorForm;
import com.ifp.opengate.boot.emum.ErrorEnum;
import com.ifp.opengate.boot.exception.AccessControlException;
import com.ifp.opengate.boot.utils.DecodeToolDelegate;

/**
 * <p>
 * 响应报文处理工具
 * </P>
 *
 * @author zhuzh@belink.com
 * @version 0.0.1
 * @className ResponseMessageTool
 * @sine 2020/4/24 15:47
 */
@Component
public final class ResponseMessageTool {

    public Map<String, Object> packResponseMessage(String cipher, List<ValidatorForm> validatorFormList,
        JSONObject respMsgObj) throws Exception {
        Map<String, Object> responseMap = new HashMap<>();
        List<ValidatorForm> responseFormList = validatorFormList.stream()
            .filter(validatorForm -> "1".equals(validatorForm.getParamDirection())).collect(Collectors.toList());
        int size = responseFormList.size();
        for (int i = 0; i < size; i++) {
            this.encodeForm(cipher, responseFormList.get(i), responseMap, respMsgObj);
        }
        return responseMap;
    }

    private void encodeForm(String cipher, ValidatorForm validatorForm, Map<String, Object> responseMap,
        JSONObject respMsgObj) throws Exception {
        if ("0".equals(validatorForm.getParamType())) {
            String fieldValue = (String)this.getFieldValue(validatorForm, respMsgObj);
            dealWithField(cipher, responseMap, validatorForm, fieldValue);
        } else {
            List<Map<String, Object>> mapList =
                (List<Map<String, Object>>)this.getFieldValue(validatorForm, respMsgObj);
            // 返回Map集合
            List<Map<String, Object>> retrunMaps = new ArrayList<>();
            // 加密处理，需要解密
            if ("1".equals(validatorForm.getIsEncode())) {
                if (!StringUtil.hasText(mapList)) {
                    throw new AccessControlException(ErrorEnum.encodeError.code(),
                        String.format(ErrorEnum.encodeError.msg(), validatorForm.getParamName()));
                }
                dealWithList(cipher, validatorForm, mapList, retrunMaps);
            } else {
                dealWithList(cipher, validatorForm, mapList, retrunMaps);
            }
            dealWithField(cipher, responseMap, validatorForm, retrunMaps);
        }
    }

    private void dealWithList(String cipher, ValidatorForm validatorForm, List<Map<String, Object>> list,
        List<Map<String, Object>> mapList) throws Exception {
        if (null == list || list.size() == 0) {
            return;
        }
        List<ValidatorForm> formList = validatorForm.getFormList();
        int size = list.size();
        for (int j = 0; j < size; j++) {
            Map<String, Object> map = new HashMap<>();
            for (int i = 0; i < formList.size(); i++) {
                ValidatorForm form = formList.get(i);
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(list.get(j)));
                encodeForm(cipher, form, map, jsonObject);
            }
            mapList.add(map);
        }
    }

    /**
     * 处理字段
     *
     * @param cipher
     * @param responseMap
     * @param validatorForm
     * @param fieldValue
     * @throws Exception
     */
    private void dealWithField(String cipher, Map<String, Object> responseMap, ValidatorForm validatorForm,
        Object fieldValue) throws Exception {
        if ("1".equals(validatorForm.getIsEncode())) {
            if (!StringUtil.hasText(fieldValue)) {
                throw new AccessControlException(ErrorEnum.encodeError.code(),
                    String.format(ErrorEnum.encodeError.msg(), validatorForm.getParamName()));
            }
            // 加密
            String decode = DecodeToolDelegate.encode(cipher, JSON.toJSONString(fieldValue), validatorForm);
            // 参数映射
            mapperKey(validatorForm, responseMap, decode);
        } else {
            // 参数映射
            mapperKey(validatorForm, responseMap, fieldValue);
        }
    }

    /**
     * 加密字段和name的映射
     *
     * @param validatorForm
     * @param responseMap
     * @param fieldValue
     */
    private void mapperKey(ValidatorForm validatorForm, Map<String, Object> responseMap, Object fieldValue) {
        if ("1".equals(validatorForm.getIsEncode())) {
            if (StringUtil.hasText(validatorForm.getEncodeMappingKey())) {
                responseMap.put(validatorForm.getEncodeMappingKey(), fieldValue);
            } else {
                responseMap.put(validatorForm.getParamName(), fieldValue);
            }
        } else {
            responseMap.put(validatorForm.getParamName(), fieldValue);
        }
    }

    /**
     * 获取相应报文里面的值
     *
     * @param validatorForm
     * @param respMsgObj
     * @return
     */
    private Object getFieldValue(ValidatorForm validatorForm, JSONObject respMsgObj) {
        Map<String, Object> body = (Map<String, Object>)respMsgObj.get("body");
        Object obj = null;
        if (StringUtil.hasText(validatorForm.getParamMappingKey())) {
            if (body != null) {
                obj = body.get(validatorForm.getParamMappingKey());
            } else {
                obj = respMsgObj.getString(validatorForm.getParamMappingKey());
            }
            if (StringUtil.hasText(obj)) {
                return obj;
            }
            return respMsgObj.get(validatorForm.getParamMappingKey());
        } else {
            if (body != null) {
                obj = body.get(validatorForm.getParamName());
            } else {
                obj = respMsgObj.getString(validatorForm.getParamName());
            }
            if (StringUtil.hasText(obj)) {
                return obj;
            }
            return respMsgObj.get(validatorForm.getParamName());
        }
    }

}
